package com.mmq.ets.util;

import com.mmq.ets.modele.AbstractForme;

public abstract class AbstractTrieurFormes {
	
	/**
	 * Effectue le tri de la liste de formes envoyé selon le style de tri passé en paramètre et renvoie une copie de la liste triée
	 * @param lstForme liste à trier
	 * @param styleTri type de tri à effectuer
	 * @return copie de la liste triée
	 * @throws CloneNotSupportedException
	 */
	public static ListeChainee<AbstractForme> trierFormes(ListeChainee<AbstractForme> lstForme, Labo2Const.ActionTrier styleTri) throws CloneNotSupportedException{
		@SuppressWarnings("unchecked")
		ListeChainee<AbstractForme> tmpLst =new ListeChainee<AbstractForme>(); 
		for(AbstractForme forme:lstForme)
		{
			tmpLst.ajouter((AbstractForme) forme.clone());
		}

		setPositionZeroXZeroY(tmpLst);
		int coordonneXY = 0;
			
		for (int i = 0; i < tmpLst.taille() - 1 ; i++){
			for (int j = i + 1; j < tmpLst.taille(); j++){
				switch (styleTri) {
				case TRIER_PAR_AREA_CROISSANT:
					if(AbstractForme.compareAire(tmpLst.get(i), tmpLst.get(j)) == 1)
					{
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_AREA_DECROISSANT:
					
					if(AbstractForme.compareAire(tmpLst.get(i), tmpLst.get(j)) == -1){
					
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					break;
				case TRIER_PAR_MAXDIS_CROISSANT:
						
					if(AbstractForme.compareMaxDist(tmpLst.get(i), tmpLst.get(j)) == 1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
					
				case TRIER_PAR_MAXDIS_DECROISSANT:
						
					if(AbstractForme.compareMaxDist(tmpLst.get(i), tmpLst.get(j)) == -1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_NSEQ_CROISSANT:
					
					if(AbstractForme.compareNseq(tmpLst.get(i), tmpLst.get(j)) == 1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_NSEQ_DECROISSANT:
					
					if(AbstractForme.compareNseq(tmpLst.get(i), tmpLst.get(j)) == -1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_TYPE_CROISSANT:
					
					if(AbstractForme.compareType(tmpLst.get(i), tmpLst.get(j)) == 1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_TYPE_DECROISSANT:
					
					if(AbstractForme.compareType(tmpLst.get(i), tmpLst.get(j)) == -1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_HAUTEUR_CROISSANT:
					
					if(AbstractForme.compareHauteur(tmpLst.get(i), tmpLst.get(j)) == 1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_HAUTEUR_DECROISSANT:
					
					if(AbstractForme.compareHauteur(tmpLst.get(i), tmpLst.get(j)) == -1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_LARGEUR_CROISSANT:
					
					if(AbstractForme.compareLargeur(tmpLst.get(i), tmpLst.get(j)) == 1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}
					
					break;
				case TRIER_PAR_LARGEUR_DECROISSANT:
					
					if(AbstractForme.compareLargeur(tmpLst.get(i), tmpLst.get(j)) == -1){
						AbstractForme tmp = tmpLst.get(i);
						tmpLst.set(i, tmpLst.get(j));
						tmpLst.set(j, tmp);
					}	
					break;
				}
			}
		}
		
		for (AbstractForme tmpForme : tmpLst){
			tmpForme.setPointDepartX(coordonneXY);
			tmpForme.setPointDepartY(coordonneXY);
			coordonneXY+=40;
		}
		
		return tmpLst;
	}
	/**
	 * Affecte les coordonnées de la forme à zéro
	 * @param tabForme forme à réinitialiser
	 */
	public static void setPositionZeroXZeroY(ListeChainee<AbstractForme> tabForme)
	{
		for(AbstractForme forme : tabForme)
		{
			forme.setPointDepartX(Labo2Const.POSITION_INITIAL_X);
			forme.setPointDepartY(Labo2Const.POSITION_INITIAL_Y);
		}
	}
}
